package com.demo.common.file;

import com.demo.common.exceptions.ServiceException;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.GetObjectResponse;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.ObjectWriteResponse;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.ErrorResponseException;
import lombok.SneakyThrows;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * minio文件系统
 */
@Component
@ConditionalOnExpression("#{'minio'.equals(environment['moudle-type.file'])}")
public class MinioFileSystem implements FileOperator, InitializingBean {

    private final String NO_FILE = "NoSuchKey";

    private MinioClient minioClient = MinioClient.builder().endpoint("http://localhost:9000").credentials("admin", "admin111").build();

    private final String DEFAULT_BUCKET = "default";

    @Override
    @SneakyThrows
    public String upload(MultipartFile file) {
        String newFileName = FileUtils.getNewFileName(file.getOriginalFilename());
        ObjectWriteResponse response = minioClient.putObject(PutObjectArgs.builder().bucket(DEFAULT_BUCKET).object(newFileName).stream(file.getInputStream(), file.getSize(), -1).build());
        return response.object();
    }

    @Override
    @SneakyThrows
    public void downLoad(String fid, HttpServletResponse response) {
        GetObjectResponse objectResponse = null;
        try {
            objectResponse = minioClient.getObject(GetObjectArgs.builder().bucket(DEFAULT_BUCKET).object(fid).build());
        } catch (ErrorResponseException e) {
            String code = e.errorResponse().code();
            if (NO_FILE.equals(code)) {
                throw new ServiceException("文件" + fid + "不存在");
            }
        }
        FileUtils.setHeaders(response, objectResponse.object());
        byte[] buffer = new byte[1024 * 8];
        int length = 0;
        while ((length = objectResponse.read(buffer)) != -1) {
            response.getOutputStream().write(buffer, 0, length);
            response.getOutputStream().flush();
        }
        objectResponse.close();
    }

    @Override
    @SneakyThrows
    public void delete(String fileName) {
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(DEFAULT_BUCKET).object(fileName).build());
    }

    @Override
    @SneakyThrows
    public void afterPropertiesSet() {
        //项目启动时检查默认bucket是否存在，不存在则创建
        boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(DEFAULT_BUCKET).build());
        if (!exists) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(DEFAULT_BUCKET).build());
        }
    }
}
